package restful.struts2;

import static java.text.MessageFormat.*;
import static org.hamcrest.Matchers.*;

import java.io.*;
import java.util.*;

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.*;
import org.hamcrest.*;
import org.junit.*;
import org.mortbay.jetty.*;
import org.mortbay.jetty.webapp.*;

public abstract class ProtocolIT {

	protected static void start(String app) throws Exception {
		WebAppContext webapp = new WebAppContext(war(app), "/");
		webapp.setParentLoaderPriority(true);
		webapp.setExtraClasspath(lib());

		server = new Server(8080);
		server.setHandler(webapp);
		server.start();
	}

	protected static String lib() {
		return userDir("src/it/resources/lib");
	}

	@AfterClass
	public static void tearDownClass() throws Exception {
		server.stop();
	}

	protected static String userDir(String path) {
		return format("{0}/{1}/{2}", System.getProperty("user.dir"), path);
	}

	protected static String war(String name) {
		return userDir("src/test/resources", name);
	}

	protected WebAppContext webapp;
	protected static Server server;
	protected String content;
	protected int status;
	protected HttpClient client;
	protected List<Header> headers;

	protected int GET(String uri) throws IOException, HttpException {
		return execute(new GetMethod(host(uri)));
	}

	protected void PUT(String uri) throws IOException, HttpException {
		execute(new PutMethod(host(uri)));
	}

	protected void DELETE(String uri) throws IOException, HttpException {
		execute(new DeleteMethod(host(uri)));
	}

	protected String host(String uri) {
		return "http://localhost:8080" + uri;
	}

	protected int execute(HttpMethod method) throws IOException, HttpException {
		status = client.executeMethod(method);
		headers = asList(method.getResponseHeaders());
		content = method.getResponseBodyAsString();
		return status;
	}

	private <T> List<T> asList(T[] array) {
		List<T> result = new LinkedList<T>();
		for (T t : array) {
			result.add(t);
		}
		return result;
	}

	@Factory
	protected static Matcher<Iterable<Header>> hasHeader(String name, String value) {
		return hasItem(new Header(name, value));
	}

	protected void POST(String uri, String attr, String name) throws IOException, HttpException {
		PostMethod method = new PostMethod(host(uri));
		NameValuePair[] data = { new NameValuePair(attr, name) };
		method.setRequestBody(data);
		execute(method);
	}

	protected void POST(String uri) throws IOException, HttpException {
		execute(new PostMethod(host(uri)));
	}

	@Before
	public void setUp() {
		client = new HttpClient();
	}

	protected static String userDir(String path, String name) {
		return format("{0}/{1}/{2}", System.getProperty("user.dir"), path, name);
	}

}
